package com.sduept.nwld.dataserver.controller.equipment.assessment;

import com.sduept.bigdata.equipment.assessment.enums.SubStationTypeEnum;
import com.sduept.bigdata.equipment.assessment.model.standardlib.StandardInspection;
import com.sduept.bigdata.equipment.assessment.model.template.AssessmentTemplate;
import com.sduept.bigdata.equipment.assessment.model.template.AssessmentTemplateItem;
import com.sduept.bigdata.equipment.assessment.service.AssessmentTemplateService;
import com.sduept.bigdata.equipment.assessment.service.InspectionPlanService;
import com.sduept.bigdata.equipment.assessment.service.StandardInspectService;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.cim.model.core.Substation;
import com.sduept.generator.ObjectId;
import com.sduept.nwld.dataserver.manager.cim.CimManager;
import com.sduept.nwld.dataserver.service.equipment.assessment.TableViewModelItemViewService;
import com.sduept.nwld.dataserver.util.LibTreeNode;
import com.sduept.permission.entity.PersonnelEntityBean;
import org.primefaces.PrimeFaces;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.util.*;

/**
 * 评价模板controller，提供增删改等操作
 * @author huangyu
 * @Date 2019年8月21日
 */
@Named
@ViewScoped
public class AssessmentTemplateController extends AbstractController {
	
	private static final long serialVersionUID = 2026431113851276368L;
	
	@Autowired
	private AssessmentTemplateService service;
	@Autowired
	private StandardInspectService standardService;
	@Autowired
	private InspectionPlanService planService;
	@Autowired
	private TableViewModelItemViewService viewService;
	@Autowired
	private CimManager cim;
	/**
	 * 模板树根节点
	 */
	private TreeNode templateRoot;
	/**
	 * 公用模板
	 */
	private TreeNode publicNode;
	/**
	 * 个人模板
	 */
	private TreeNode privateNode;
	/**
	 * 历史模板
	 */
	private TreeNode historyNode;
	
	private final String publicTemlplate = "公用模板";
	private final String privateTemlplate = "个人模板";
	private final String historyTemlplate = "历史模板";
	
	private TreeNode selectedNode;
	private AssessmentTemplate currentTemplate;
	private AssessmentTemplate selectedTemplate;
	
	private AssessmentTemplateItem selectedTemplateItem;
	
	private List<TemplateItemDTO> dtos = new ArrayList<TemplateItemDTO>();
	private List<TableViewModelItem> templateDetails;
	private String tableTitle;
	
	/**
	 * 模板类型，0：公共模板；1：私有模板
	 */
	private String templateType;
	
	/**
	 * 模板下选中的变电站
	 */
	private List<Substation> selectedStataions = new ArrayList<Substation>();
	
	private boolean showTemplateEdit = false;
	private boolean showTemplateItemEdit = false;
	/**
	 * 新建模板时用户可选择的评价标准根节点
	 */
	private List<StandardInspection> avaliableStands;
	@PostConstruct
	public void init() {
		initTemplateTree();
		try {
			avaliableStands = standardService.findAvailableRoot();
		} catch (Exception e) {
			e.printStackTrace();
			addErrorMessage("获取可用的评价标准出错");
		}
	}

	/**
	 * 初始化模板树
	 */
	private void initTemplateTree() {
		templateRoot = new LibTreeNode("Root",null);
		publicNode = new LibTreeNode("templateType",publicTemlplate, templateRoot);
		privateNode = new LibTreeNode("templateType",privateTemlplate, templateRoot);
		historyNode = new LibTreeNode("templateType",historyTemlplate, templateRoot);
		genPublicTemplateNode();
		genPrivateTemplateNode();
		genHistoryTemplateNode();
	}

	/**
	 * 生成公用模板节点
	 */
	private void genPublicTemplateNode() {
		List<AssessmentTemplate> publicTemplates = service.findPublicTemplates();
		if(publicTemplates.size()>0) {
			// 右侧页面表格展示第一个模板的内容
			genTemplateItemDTO(publicTemplates.get(0));
		}
		for (AssessmentTemplate template : publicTemplates) {
			TreeNode pNode = new LibTreeNode("template",template, publicNode);
			Set<AssessmentTemplateItem> items = service.findAssessmentTemplateItemByAssessmentTemplateId(template.getId());
			for (AssessmentTemplateItem item : items) {
				new LibTreeNode("templateItem",item, pNode);
			}
//			pNode.setExpanded(true);
		}
		publicNode.setExpanded(true);
	}
	/**
	 * 生成私有模板节点
	 */
	private void genPrivateTemplateNode() {
		List<AssessmentTemplate> privateTemplates = getPrivateTemplatesByLoginUser();
		for (AssessmentTemplate template : privateTemplates) {
			TreeNode pNode = new LibTreeNode("template",template, privateNode);
			Set<AssessmentTemplateItem> items = service.findAssessmentTemplateItemByAssessmentTemplateId(template.getId());
			for (AssessmentTemplateItem item : items) {
				new LibTreeNode("templateItem",item, pNode);
			}
		}
		privateNode.setExpanded(true);
	}
	/**
	 * 根据当前用户的权限，获取当前用户可见的私有模板
	 * @return
	 */
	private List<AssessmentTemplate> getPrivateTemplatesByLoginUser() {
		PersonnelEntityBean user = getCurrentUser();
		String userId = null;
		if(null != user) {
			userId = user.getId();
		}
		try {
			List<AssessmentTemplate> templates = service.findPersonalAssessmentTemplateByUserId(userId);
			sortTemplateByNum(templates);
			return templates;
		} catch (Exception e) {
			e.printStackTrace();
			addErrorMessage("获取私人模板失败");
			return null;
		}
	}
	/**
	 * 生成历史模板节点
	 */
	private void genHistoryTemplateNode() {
		List<AssessmentTemplate> historyTemplates = service.findHistoryTemplates();
		for (AssessmentTemplate template : historyTemplates) {
			TreeNode pNode = new LibTreeNode("template",template, historyNode);
			Set<AssessmentTemplateItem> items = service.findAssessmentTemplateItemByAssessmentTemplateId(template.getId());
			for (AssessmentTemplateItem item : items) {
				new LibTreeNode("templateItem",item, pNode);
			}
		}
		historyNode.setExpanded(true);
	}
	
	/**
	 * 选择树节点
	 * @param event
	 */
	public void onNodeSelect(NodeSelectEvent event) {
		selectedNode = event.getTreeNode();
		showTemplateEdit = false;
		showTemplateItemEdit = false;
		if(selectedNode.getData() instanceof String) {
			selectedTemplate = null;
			selectedTemplateItem = null;
		} else if(selectedNode.getData() instanceof AssessmentTemplate) {
			// 选中的是模板
			selectedTemplate = (AssessmentTemplate) selectedNode.getData();
			if (selectedTemplate.getAvailable()) {
				showTemplateEdit = true;
				showTemplateItemEdit = false;
			}
			// 渲染右侧表格
			genTemplateItemDTO(selectedTemplate);
		} else if(selectedNode.getData() instanceof AssessmentTemplateItem) {
			// 选中的是模板项
			selectedTemplateItem = (AssessmentTemplateItem) selectedNode.getData();
			// 渲染右侧表格
			genTemplateItemDTO(selectedTemplateItem);
			try {
				selectedTemplate = service.findAssessmentTemplatesByItem(selectedTemplateItem.getId());
				if (selectedTemplate.getAvailable()) {
					showTemplateEdit = false;
					showTemplateItemEdit = true;
				}
			} catch (Exception e) {
				addErrorMessage("通过模板项获取模板失败");
			}
		}
	}

	public class TemplateItemDTO {
		/**
		 * 模板
		 */
		private AssessmentTemplate template;
		/**
		 * 类型
		 */
		private SubStationTypeEnum type;
		/**
		 * 模板项
		 */
		private AssessmentTemplateItem templateItem;
		/**
		 * 该模板项的评价标准
		 */
		private List<StandardInspection> stands;
		public AssessmentTemplate getTemplate() {
			return template;
		}
		public AssessmentTemplateItem getTemplateItem() {
			return templateItem;
		}
		public List<StandardInspection> getStands() {
			return stands;
		}
		public void setTemplate(AssessmentTemplate template) {
			this.template = template;
		}
		public void setTemplateItem(AssessmentTemplateItem templateItem) {
			this.templateItem = templateItem;
		}
		public void setStands(List<StandardInspection> stands) {
			this.stands = stands;
		}
		public SubStationTypeEnum getType() {
			return type;
		}
		public void setType(SubStationTypeEnum type) {
			this.type = type;
		}
	}
	
	/**
	 * 树节点展开
	 * @param event
	 */
	public void onNodeExpand(NodeExpandEvent event) {
	}
	
	/**
	 * 新建模板
	 */
	public void preCreateTemplate() {
		selectedTemplate = null;
		currentTemplate = new AssessmentTemplate();
		currentTemplate.setId(ObjectId.get().toString());
		List<AssessmentTemplate> lt = service.findAll();
		currentTemplate.setNum(lt.size()+1+"");
		currentTemplate.setUpdateTime(new Date());
		currentTemplate.setAvailable(true);
		try {
			List<StandardInspection> stands = standardService.findAvailableRoot();
			if(stands.size()>0) {
				currentTemplate.setStandardVersion(stands.get(0).getId());
			}
		} catch (Exception e) {
			e.printStackTrace();
			addErrorMessage("获取可用版本数据过程中发生错误");
		}
	}
	
	/**
	 * 编辑模板
	 */
	public void preEditTemplate() {
		currentTemplate = selectedTemplate;
	}
	
	/**
	 * 保存模板
	 */
	public void saveTemplate() {
		if("1".equals(templateType)) {
			// 私有模板
			PersonnelEntityBean person = getCurrentUser();
			if(null != person) {
				currentTemplate.setPurviewId(person.getId());
			}
		} else if ("0".equals(templateType)) {
			// 公共模板
			currentTemplate.setPurviewId(null);
		}
		saveTemplateItems(selectedStataions);
		service.createOrUpdate(currentTemplate);
		addSuccessMessage("模板保存成功");
		initTemplateTree();
		selectedStataions.clear();
	}
	
	/**
	 * 删除模板，有子模板项时，级联删除
	 */
	private void deleteTemplate() {
		try {
			service.deleteByAssessmentTemplateId(selectedTemplate.getId());
			selectedTemplate = null;
			addSuccessMessage("删除成功");
		} catch (Exception e) {
			e.printStackTrace();
			addErrorMessage("删除模板失败");
		}
	}

	/**
	 * 打开变电站多选择器
	 */
	public void openStationMultipleSelectorDialog() {
		Map<String, Object> options = new HashMap<String, Object>();
		options.put("resizable", true);
		options.put("draggable", true);
		options.put("modal", true);
		options.put("width", 620);
		options.put("height", 650);
		
		List<String> stationIds = new ArrayList<String>();
		if(null != selectedTemplate) {
			Set<AssessmentTemplateItem> templateItems = service.findAssessmentTemplateItemByAssessmentTemplateId(selectedTemplate.getId());
			for (AssessmentTemplateItem item : templateItems) {
				stationIds.add(item.getSubstationid());
			}
		}
		Map<String, List<String>> params = new HashMap<>();
		params.put("stationIds", stationIds);
		
		PrimeFaces.current().dialog().openDynamic("/ui/common/subStation_multiple_selector_groupByDesorg.xhtml",  options,params);
	}
	
	/**
	 * 选择变电站
	 * @param event
	 */
	@SuppressWarnings("unchecked")
	public void onStationsChosen(SelectEvent event) {
		selectedStataions = (List<Substation>) event.getObject();
	}
	
	/**
	 * 选择变电站作为模板项进行保存
	 * @param stations
	 * @return 
	 */
	private void saveTemplateItems(List<Substation> stations) {
		List<StandardInspection> selectedStandardRoot = new ArrayList<StandardInspection>();
		String standardId = currentTemplate.getStandardVersion();
		for (StandardInspection stand : avaliableStands) {
			if(standardId.equals(stand.getId())) {
				selectedStandardRoot.add(stand);
			}
		}
		// 修改已有的模板项
		Set<AssessmentTemplateItem> exitItems = service.findAssessmentTemplateItemByAssessmentTemplateId(currentTemplate.getId());
		for (AssessmentTemplateItem item : exitItems) {
			item.setStandardInspections(selectedStandardRoot);
		}
		for (AssessmentTemplateItem item : exitItems) {
			service.createOrUpdateItem(item);
		}
		// 新选择的模板项
		List<AssessmentTemplateItem> newAddItems = new ArrayList<AssessmentTemplateItem>();
		try {
			List<Substation> result = removeExistStation(stations, currentTemplate);
			for (Substation substation : result) {
				AssessmentTemplateItem item = new AssessmentTemplateItem();
				item.setSubstationid(substation.getId());
				item.setName(substation.getName());
				item.setAssessmentTemplate(currentTemplate);
				item.setUpdateTime(new Date());
				item.setStandardInspections(selectedStandardRoot);
				newAddItems.add(item);
			}
			for (AssessmentTemplateItem item : newAddItems) {
				service.createOrUpdateItem(item);
			}
		} catch (Exception e) {
			e.printStackTrace();
			addErrorMessage("获取可用的标准出错");
		}
	}
	
	/**
	 * 新选择的变电站list中，如果在模板的模板项中已存在的，将其移除掉。
	 * @param stations
	 * @param template
	 * @return
	 */
	private List<Substation> removeExistStation(List<Substation> stations,AssessmentTemplate template) {
		List<Substation> result = new ArrayList<Substation>();
		Set<AssessmentTemplateItem> items = service.findAssessmentTemplateItemByAssessmentTemplateId(template.getId());
		List<String> ids = new ArrayList<String>();
		for (AssessmentTemplateItem item : items) {
			ids.add(item.getSubstationid());
		}
		for (Substation station : stations) {
			if(!ids.contains(station.getId())) {
				result.add(station);
			}
		}
		return result;
	}
	
	/**
	 * 编辑模板项
	 */
	public void preEditTemplateItem() {
		try {
			selectedTemplate = service.findAssessmentTemplatesByItem(selectedTemplateItem.getId());
		} catch (Exception e) {
			addErrorMessage("通过模板项获取模板失败");
		}
	}
	
	/**
	 * 保存模板项
	 */
	public void saveTemplateItemEdit() {
		service.createOrUpdateItem(selectedTemplateItem);
		addSuccessMessage("保存成功");
		genTemplateItemDTO(selectedTemplateItem);
		showTemplateItemDetail(selectedTemplateItem);
		initTemplateTree();
	}
	/**
	 * 获取模板所选择的评价标准的类型（常规站、智能站）
	 * @param template
	 * @return
	 */
	private SubStationTypeEnum getTemplateSubstationType(AssessmentTemplate template) {
		String standartId = template.getStandardVersion();
		StandardInspection standard = standardService.findById(standartId);
		if(null != standard) {
			return standard.getStationType();
		} else {
			return null;
		}
	}
	/**
	 * 通过模板项获取TemplateItemDTO
	 * @param item
	 */
	private void genTemplateItemDTO(AssessmentTemplateItem item) {
		dtos.clear();
		try {
			TemplateItemDTO dto = new TemplateItemDTO();
			List<StandardInspection> stands = service.findStandardInspectionbyItem(item.getId());
			dto.setStands(stands);
			dto.setTemplateItem(item);
			AssessmentTemplate template = service.findAssessmentTemplatesByItem(item.getId());
			SubStationTypeEnum type = getTemplateSubstationType(template);
			dto.setType(type);
			dto.setTemplate(template);
			dtos.add(dto);
		} catch (Exception e) {
			e.printStackTrace();
			addErrorMessage("通过模板项获取评价标准失败");
		}
	}
	/**
	 * 通过模板获取TemplateItemDTO
	 * @param template
	 */
	private void genTemplateItemDTO(AssessmentTemplate template) {
		dtos.clear();
		SubStationTypeEnum type = getTemplateSubstationType(template);
		Set<AssessmentTemplateItem> items = service.findAssessmentTemplateItemByAssessmentTemplateId(template.getId());
		for (AssessmentTemplateItem item : items) {
			TemplateItemDTO dto = new TemplateItemDTO();
			dto.setTemplate(template);
			dto.setTemplateItem(item);
			dto.setType(type);
			try {
				List<StandardInspection> stands = service.findStandardInspectionbyItem(item.getId());
				dto.setStands(stands);
			} catch (Exception e) {
				e.printStackTrace();
				addErrorMessage("获取模板项的检查标准出错");
			}
			dtos.add(dto);
		}
	}
	
	public void delete() {
		if(selectedNode.getData() instanceof AssessmentTemplate) {
			deleteTemplate();
		} else if(selectedNode.getData() instanceof AssessmentTemplateItem) {
			deleteTemplateItem();
		}
		initTemplateTree();
	}
	
	/**
	 * 删除子模板项
	 */
	private void deleteTemplateItem() {
		service.deleteAssessmentTemplateItemById(selectedTemplateItem.getId());
		selectedTemplateItem = null;
		addSuccessMessage("删除成功");
	}
	
	/**
	 * 编辑模板项的评价标准
	 * @param event
	 */
	@SuppressWarnings("unchecked")
	public void onStandardsChosenWhenEdit(SelectEvent event) {
		// 选中的标准评价项目
		List<StandardInspection> allStandards = (List<StandardInspection>) event.getObject();
		if(null == allStandards) {
			addErrorMessage("请选择评价项目");
			return ;
		}
		// 需要维护进模板的评价项目，即移除了子节点后的标准评价项目
		List<StandardInspection> pStandards = removeChildStandard(allStandards);
		selectedTemplateItem.setStandardInspections(pStandards);
		// 获取模板项的父，即模板
		try {
			AssessmentTemplate template = service.findAssessmentTemplatesByItem(selectedTemplateItem.getId());
			if(null == template.getStandardVersion() && null != allStandards.get(0)) {
				String version = allStandards.get(0).getStandardVersion();
				template.setStandardVersion(version);
				service.createOrUpdate(template);
			}
		} catch (Exception e) {
			addErrorMessage("通过模板项获取模板失败");
		}
	}
	
	/**
	 * List<StandardInspection>中，如果某个节点的子节点存在，则移除子节点，只保留父节点
	 * @param standards
	 * @return
	 */
	private List<StandardInspection> removeChildStandard(List<StandardInspection> standards) {
		List<StandardInspection> results = new ArrayList<StandardInspection>();
		Map<StandardInspection,StandardInspection/*parent*/> map = new HashMap<StandardInspection,StandardInspection>();
		for (StandardInspection stand : standards) {
			StandardInspection pStand = standardService.findByChild(stand.getId());
			if(null == pStand) {
				// 说明选中了根节点，仅返回根节点即可
				results.add(stand);
				return results;
			} else {
				map.put(stand, pStand);
			}
		}
		for (StandardInspection stand : map.keySet()) {
			StandardInspection pStand = map.get(stand);
			if(!map.containsKey(pStand)) {
				results.add(stand);
			}
		}
		return results;
	}

	/**
	 * 以表格的形式展示模板项的详细信息，渲染页面右侧的表格
	 * @param item 
	 */
	public void showTemplateItemDetail(AssessmentTemplateItem item) {
		tableTitle = item.getName();
		templateDetails = viewService.getTableViewModelItemListBytemplate(item);
	}
	
	public void openStandardSelectorDialog() {
        Map<String, Object> options = new HashMap<String, Object>();
		options.put("resizable", true);
		options.put("draggable", true);
		options.put("modal", true);
		options.put("width", 620);
		options.put("height", 650);
		
		Map<String, List<String>> params = new HashMap<>();
		try {
			List<StandardInspection> stands = service.findStandardInspectionbyItem(selectedTemplateItem.getId());
			List<String> lt = new ArrayList<String>();
			if(null != stands) {
				for (StandardInspection stand : stands) {
					lt.add(stand.getId());
				}
			}
			params.put("selectedStands", lt);
		} catch (Exception e) {
			addErrorMessage("通过模板项获取评价标准失败");
		}
		PrimeFaces.current().dialog().openDynamic("/ui/common/standard_selector_multiple.xhtml",  options,params);
    }
	
	/**
	 * 打开模板详情查看框
	 */
	public void openTemplateItemDetailDialog() {
		Map<String, Object> options = new HashMap<String, Object>();
		options.put("resizable", true);
		options.put("draggable", true);
		options.put("modal", true);
		options.put("width", 620);
		options.put("height", 650);
		Map<String, List<String>> params = new HashMap<>();
		List<String> templateIds = new ArrayList<>();
        templateIds.add(selectedTemplate.getId());
		params.put("templateId", templateIds);
		PrimeFaces.current().dialog().openDynamic("/ui/common/assessmentTemplate_detail_lookup.xhtml",  options,params);
	}
	
	/**
	 * 获取模板项的变电站名称
	 * @return
	 */
	public String getStationName() {
		if(null == selectedTemplateItem) {
			return null;
		}
		String id = selectedTemplateItem.getSubstationid();
		Substation station = cim.getStationById(id);
		if(null != station) {
			return station.getName();
		} else {
			return null;
		}
	}
	
	private void sortTemplateByNum(List<AssessmentTemplate> list) {
		Collections.sort(list, new Comparator<AssessmentTemplate>() {
			@Override
			public int compare(AssessmentTemplate o1, AssessmentTemplate o2) {
				if(Integer.parseInt(o1.getNum())>Integer.parseInt(o2.getNum())) {
					return 1;
				} else if (Integer.parseInt(o1.getNum())<Integer.parseInt(o2.getNum())) {
					return -1;
				} else {
					return 0;
				}
			}
		});
	}
	
	public TreeNode getTemplateRoot() {
		return templateRoot;
	}

	public void setTemplateRoot(TreeNode templateRoot) {
		this.templateRoot = templateRoot;
	}

	public AssessmentTemplate getCurrentTemplate() {
		return currentTemplate;
	}

	public void setCurrentTemplate(AssessmentTemplate currentTemplate) {
		this.currentTemplate = currentTemplate;
	}

	public AssessmentTemplate getSelectedTemplate() {
		return selectedTemplate;
	}

	public void setSelectedTemplate(AssessmentTemplate selectedTemplate) {
		this.selectedTemplate = selectedTemplate;
	}

	public AssessmentTemplateItem getSelectedTemplateItem() {
		return selectedTemplateItem;
	}

	public void setSelectedTemplateItem(AssessmentTemplateItem selectedTemplateItem) {
		this.selectedTemplateItem = selectedTemplateItem;
	}

	public TreeNode getSelectedNode() {
		return selectedNode;
	}

	public void setSelectedNode(TreeNode selectedNode) {
		this.selectedNode = selectedNode;
	}
	
	public List<TableViewModelItem> getTemplateDetails() {
		return templateDetails;
	}
	
	public void setTemplateDetails(List<TableViewModelItem> templateDetails) {
		this.templateDetails = templateDetails;
	}
	
	public String getTemplateType() {
		return templateType;
	}
	
	public void setTemplateType(String templateType) {
		this.templateType = templateType;
	}

	public boolean isShowTemplateEdit() {
		return showTemplateEdit;
	}

	public void setShowTemplateEdit(boolean showTemplateEdit) {
		this.showTemplateEdit = showTemplateEdit;
	}

	public boolean isShowTemplateItemEdit() {
		return showTemplateItemEdit;
	}

	public void setShowTemplateItemEdit(boolean showTemplateItemEdit) {
		this.showTemplateItemEdit = showTemplateItemEdit;
	}

	public List<TemplateItemDTO> getDtos() {
		return dtos;
	}

	public void setDtos(List<TemplateItemDTO> dtos) {
		this.dtos = dtos;
	}

	public String getTableTitle() {
		return tableTitle;
	}

	public void setTableTitle(String tableTitle) {
		this.tableTitle = tableTitle;
	}

	public List<StandardInspection> getAvaliableStands() {
		return avaliableStands;
	}

	public void setAvaliableStands(List<StandardInspection> avaliableStands) {
		this.avaliableStands = avaliableStands;
	}

}
